import ffmpeg
import io
import logging
from typing import Dict, Optional, List
from pathlib import Path
import tempfile
import os
from pydub import AudioSegment
from app.utils.file_utils import temp_file_manager

logger = logging.getLogger(__name__)

class AudioService:
    SUPPORTED_FORMATS = ['mp3', 'wav', 'ogg', 'aac', 'flac']
    
    @staticmethod
    async def convert_format(content: bytes, target_format: str) -> bytes:
        """
        转换音频格式
        
        Args:
            content: 音频文件内容
            target_format: 目标格式
        
        Returns:
            bytes: 转换后的音频内容
        """
        if target_format not in AudioService.SUPPORTED_FORMATS:
            raise ValueError(f"不支持的格式: {target_format}")
            
        with temp_file_manager() as tmp_mgr:
            try:
                # 创建临时文件
                temp_in_path = tmp_mgr.create_temp_file('.mp3')
                with open(temp_in_path, 'wb') as f:
                    f.write(content)

                # 加载音频
                audio = AudioSegment.from_file(temp_in_path)
                
                # 导出为目标格式
                output = io.BytesIO()
                audio.export(output, format=target_format)
                return output.getvalue()

            except Exception as e:
                logger.error(f"音频格式转换失败: {str(e)}")
                raise

    @staticmethod
    async def compress_audio(content: bytes, bitrate: int) -> bytes:
        """压缩音频文件"""
        with temp_file_manager() as tmp_mgr:
            try:
                # 创建临时文件
                temp_in_path = tmp_mgr.create_temp_file('.mp3')
                with open(temp_in_path, 'wb') as f:
                    f.write(content)
                
                temp_out_path = tmp_mgr.create_temp_file('.mp3')
            
                # 执行压缩
                stream = ffmpeg.input(temp_in_path)
                stream = ffmpeg.output(
                    stream,
                    temp_out_path,
                    acodec='libmp3lame',
                    **{'b:a': f'{bitrate}k'},
                    map_metadata='-1'
                )
                ffmpeg.run(stream, overwrite_output=True)
                
                # 读取结果
                with open(temp_out_path, 'rb') as f:
                    result = f.read()
                    
                return result
                
            except Exception as e:
                logger.error(f"音频压缩失败: {str(e)}")
                raise

    @staticmethod
    async def trim_audio(content: bytes, start_time: float, end_time: float) -> bytes:
        """剪辑音频"""
        with temp_file_manager() as tmp_mgr:
            try:
                # 创建临时文件
                temp_path = tmp_mgr.create_temp_file('.mp3')
                with open(temp_path, 'wb') as f:
                    f.write(content)

                # 加载音频
                audio = AudioSegment.from_file(temp_path)
                
                # 转换时间为毫秒
                start_ms = int(start_time * 1000)
                end_ms = int(end_time * 1000)
                
                # 剪辑音频
                trimmed = audio[start_ms:end_ms]
                
                # 导出
                output = io.BytesIO()
                trimmed.export(output, format='mp3')
                return output.getvalue()

            except Exception as e:
                logger.error(f"音频剪辑失败: {str(e)}")
                raise

    @staticmethod
    async def merge_audio(contents: List[bytes]) -> bytes:
        """合并多个音频文件"""
        with temp_file_manager() as tmp_mgr:
            try:
                combined = AudioSegment.empty()

                for content in contents:
                    # 创建临时文件
                    temp_path = tmp_mgr.create_temp_file('.mp3')
                    with open(temp_path, 'wb') as f:
                        f.write(content)

                    # 添加到合并音频
                    audio = AudioSegment.from_file(temp_path)
                    combined += audio

                # 导出
                output = io.BytesIO()
                combined.export(output, format='mp3')
                return output.getvalue()

            except Exception as e:
                logger.error(f"音频合并失败: {str(e)}")
                raise 